package com.eos.common.tool;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import com.hf.utils.StringUtil;

/**
 * 工具类
 * @author Administrator
 *
 */
public class ObjectUtils {
	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat();
	private static final String POSSIBLE_CHARS="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
	
	/**
	 * 将时间转换成字符串
	 * @param d
	 * @param formatPattern 时间格式; 如: yyyy-MM-dd HH:mm,  yyyy/MM/dd等
	 * @return
	 */
	public static String formatDate(Date d, String formatPattern){
		if(d == null)
			d = new Date(System.currentTimeMillis());
		if(StringUtil.isEmpty(formatPattern))
			DATE_FORMAT.applyPattern("yyyy-MM-dd HH:mm:ss");
		else
			DATE_FORMAT.applyPattern(formatPattern);
		return DATE_FORMAT.format(d);
	}
	
	 /** 
     * 生产一个指定长度的随机字符串 
     * @param length 字符串长度 
     * @return 
     */  
    public static String generateRandomString(int length) {  
        StringBuilder sb = new StringBuilder(length);  
        SecureRandom random = new SecureRandom();  
        for (int i = 0; i < length; i++) {  
            sb.append(POSSIBLE_CHARS.charAt(random.nextInt(POSSIBLE_CHARS.length())));  
        }  
        return sb.toString();  
    }  
    
    /**
	 * 转换钱的格式, 对其四舍五入
	 * @param moeny
	 * @param pattern(格式: 0.00, 0.0等)
	 * @return
	 */
	public static double formatMoney(double moeny, String pattern){
		if(StringUtil.isEmpty(pattern)){
			pattern = "0.00";
		}
		DecimalFormat df = new DecimalFormat();
		df.applyPattern(pattern);
		String formatMoney = df.format(moeny);
		return Double.parseDouble(formatMoney);
	}
	
    /**
     * 判断字符串是否是整数, 小数
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
		return Pattern.compile("([1-9]+[0-9]*|0)(\\.[\\d]+)?").matcher(str).matches();  
	}
    
    /**
     * 将集合转换成json字符串
     * @param l
     * @return
     */
    @SuppressWarnings("rawtypes")
	public final static String listToJson(List objList) {
    	StringBuilder json = new StringBuilder();
        json.append("[");
        if (objList != null && objList.size() > 0) {
            for (Object obj : objList) {
                json.append(objectToJson(obj));
                json.append(",");
            }
            json.setCharAt(json.length() - 1, ']');
        } else {
            json.append("]");
        }
        return json.toString();
	} 
    
    public static String objectToJson(Object obj) {
        StringBuilder json = new StringBuilder();
        if (obj == null) {
            json.append("\"\"");
        } else if (obj instanceof String || obj instanceof Integer
                || obj instanceof Float || obj instanceof Boolean
                || obj instanceof Short || obj instanceof Double
                || obj instanceof Long || obj instanceof BigDecimal
                || obj instanceof BigInteger || obj instanceof Byte) {
            json.append("\"").append(stringToJson(obj.toString())).append("\"");
        } else if (obj instanceof Object[]) {
            json.append(arrayToJson((Object[]) obj));
        } else if (obj instanceof List) {
            json.append(listToJson((List<?>) obj));
        } else if (obj instanceof Map) {
            json.append(mapToJson((Map<?, ?>) obj));
        } else if (obj instanceof Set) {
            json.append(setToJson((Set<?>) obj));
        } else {
            json.append(beanToJson(obj));
        }
        return json.toString();
    }
    
    public static String beanToJson(Object bean) {
        StringBuilder json = new StringBuilder();
        json.append("{");
        PropertyDescriptor[] props = null;
        try {
            props = Introspector.getBeanInfo(bean.getClass(), Object.class).getPropertyDescriptors();
            if (props != null) {
                for (int i = 0; i < props.length; i++) {
                    String name = objectToJson(props[i].getName());
                    String value = objectToJson(props[i].getReadMethod().invoke(bean));
                    json.append(name);
                    json.append(":");
                    json.append(value);
                    json.append(",");
                }
                json.setCharAt(json.length() - 1, '}');
            } else {
                json.append("}");
            }
        } catch (IntrospectionException e) {
        	e.printStackTrace();
        } catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
        return json.toString();
    }

    /**
     * 对象数组转换为Json
     * @param array
     * @return
     */
    public static String arrayToJson(Object[] array) {
        StringBuilder json = new StringBuilder();
        json.append("[");
        if (array != null && array.length > 0) {
            for (Object obj : array) {
                json.append(objectToJson(obj));
                json.append(",");
            }
            json.setCharAt(json.length() - 1, ']');
        } else {
            json.append("]");
        }
        return json.toString();
    }

    /**
     * Map集合转换为Json
     * @param map
     * @return
     */
    public static String mapToJson(Map<?, ?> map) {
        StringBuilder json = new StringBuilder();
        json.append("{");
        if (map != null && map.size() > 0) {
            for (Object key : map.keySet()) {
                json.append(objectToJson(key));
                json.append(":");
                json.append(objectToJson(map.get(key)));
                json.append(",");
            }
            json.setCharAt(json.length() - 1, '}');
        } else {
            json.append("}");
        }
        return json.toString();
    }

    /**
     * Set集合转为Json
     * @param set
     * @return
     */
    public static String setToJson(Set<?> set) {
        StringBuilder json = new StringBuilder();
        json.append("[");
        if (set != null && set.size() > 0) {
            for (Object obj : set) {
                json.append(objectToJson(obj));
                json.append(",");
            }
            json.setCharAt(json.length() - 1, ']');
        } else {
            json.append("]");
        }
        return json.toString();
    }

    /**
     * 字符串转换为Json
     * @param s
     * @return
     */
    public static String stringToJson(String s) {
        if (s == null)
            return "";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            switch (ch) {
            case '"':
                sb.append("\\\""); break;
            case '\\':
                sb.append("\\\\");  break;
            case '\b':
                sb.append("\\b"); break;
            case '\f':
                sb.append("\\f");  break;
            case '\n':
                sb.append("\\n");  break;
            case '\r':
                sb.append("\\r");  break;
            case '\t':
                sb.append("\\t"); break;
            case '/':
                sb.append("\\/");  break;
            default:
                if (ch >= '\u0000' && ch <= '\u001F') {
                    String ss = Integer.toHexString(ch);
                    sb.append("\\u");
                    for (int k = 0; k < 4 - ss.length(); k++) {
                        sb.append('0');
                    }
                    sb.append(ss.toUpperCase());
                } else {
                    sb.append(ch);
                }
            }
        }
        return sb.toString();
    }
    
}
